 
import Crypto from 'crypto-js';
import * as Base64 from 'js-base64'; 
export default {
	 timestampToTime(timestamp) {
	        var date = new Date(timestamp );//时间戳为10位需*1000，时间戳为13位的话不需乘1000
	        var Y = date.getFullYear() + '-';
	        var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1):date.getMonth()+1) + '-';
	        var D = (date.getDate()< 10 ? '0'+date.getDate():date.getDate())+ ' ';
	        var h = (date.getHours() < 10 ? '0'+date.getHours():date.getHours())+ ':';
	        var m = (date.getMinutes() < 10 ? '0'+date.getMinutes():date.getMinutes()) + ':';
	        var s = date.getSeconds() < 10 ? '0'+date.getSeconds():date.getSeconds();
	        return Y+M+D+h+m+s;
	    }, 
	/**
	 * @description 格式化时间
	 * @param {String|Number} dateTime 需要格式化的时间戳
	 * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
	 * @returns {string} 返回格式化后的字符串
	 */
	timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
		let date
		// 若传入时间为假值，则取当前时间
		if (!dateTime) {
			date = new Date()
		}
		// 若为unix秒时间戳，则转为毫秒时间戳（逻辑有点奇怪，但不敢改，以保证历史兼容）
		else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
			date = new Date(dateTime * 1000)
		}
		// 若用户传入字符串格式时间戳，new Date无法解析，需做兼容
		else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
			date = new Date(Number(dateTime))
		}
		// 处理平台性差异，在Safari/Webkit中，new Date仅支持/作为分割符的字符串时间
		// 处理 '2022-07-10 01:02:03'，跳过 '2022-07-10T01:02:03'
		else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) {
			date = new Date(dateTime.replace(/-/g, '/'))
		}
		// 其他都认为符合 RFC 2822 规范
		else {
			date = new Date(dateTime)
		}
	
		const timeSource = {
			'y': date.getFullYear().toString(), // 年
			'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月
			'd': date.getDate().toString().padStart(2, '0'), // 日
			'h': date.getHours().toString().padStart(2, '0'), // 时
			'M': date.getMinutes().toString().padStart(2, '0'), // 分
			's': date.getSeconds().toString().padStart(2, '0') // 秒
			// 有其他格式化字符需求可以继续添加，必须转化成字符串
		}
	
		for (const key in timeSource) {
			const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
			if (ret) {
				// 年可能只需展示两位
				const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
				formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
			}
		}
	
		return formatStr
	},
	/**
	 * @author 曹连存 2024年3月8日15:45:51
	 * getSignature 
	 * @description 生成计算机签名
	 * @param {String} policyEncoded 通过Base64编码的数据
	 * @param {String} SecretKey 秘钥
	 * @return {String} 返回计算机签名
	 * @example  let signature =  getSignature()
	 */
	getSignature(policyEncoded, SecretKey) {
		// 利用SK对Base64编码后的policy结果进行HMAC-SHA1签名计算
		const bytes = Crypto.HmacSHA1(policyEncoded, SecretKey);
		// 对计算结果进行Base64编码，得到最终的签名信息
		const signature = Crypto.enc.Base64.stringify(bytes);
		return signature;
	},
	/**
	 * @author 曹连存 2024年3月8日15:49:08
	 * getPolicyEncode 
	 * @description 对数据进行Base64编码的数据 返回 policy
	 * @param {Object} policy 需要编码的数据 
	 * @return {String} 返回处理好的数据
	 * @example  let policyEncode =  getPolicyEncode()
	 */
	getPolicyEncode(policy) {
		const encodedPolicy = Base64.encode(JSON.stringify(policy));
		return encodedPolicy;
	},
	/**
	 * @author 曹连存 2024年3月8日15:38:49
	 * getUUID 
	 * @description 获取UUID 
	 * @return {String} 返回UUID
	 * @example  let UUID =  getUUID()
	 */
	getUUID() {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			const r = (Math.random() * 16) | 0
			const v = c == 'x' ? r : (r & 0x3) | 0x8
			return v.toString(16)
		})
	},
	/**
	 * @author 曹连存 2024年3月8日15:40:51
	 * getNowDate 
	 * @param {Date} time 指定时间
	 * @param {String} model 模式 默认为空返回 YYYY-MM-DD 当前可选 huawei 返回 YYYY-MM-DD T HH:MM:SS Z
	 * @description 获取当前时间 YYYY-MM-DD 或  YYYY-MM-DD T HH:MM:SS Z
	 * @return {String} 对应格式的时间
	 * @example  let now =  getNowDate()
	 */
	getNowDate(time = null, model = "") {
		const date = time || new Date();
		const sign2 = ":";
		const year = date.getFullYear(); // 年
		let month = date.getMonth() + 1; // 月
		let day = date.getDate(); // 日
		let hour = date.getHours(); // 时
		let minutes = date.getMinutes(); // 分
		let seconds = date.getSeconds(); //秒
		const weekArr = [
			"星期一",
			"星期二",
			"星期三",
			"星期四",
			"星期五",
			"星期六",
			"星期天",
		];
		const week = weekArr[date.getDay()];
		// 给一位数的数据前面加 “0”
		if (month >= 1 && month <= 9) {
			month = "0" + month;
		}
		if (day >= 0 && day <= 9) {
			day = "0" + day;
		}
		if (hour >= 0 && hour <= 9) {
			hour = "0" + hour;
		}
		if (minutes >= 0 && minutes <= 9) {
			minutes = "0" + minutes;
		}
		if (seconds >= 0 && seconds <= 9) {
			seconds = "0" + seconds;
		}
		switch (model) {
			case "huawei":
				return `${year}-${month}-${day}T${hour}:${minutes}:${seconds}Z`;
			case "orderTime":
				return `${year}-${month}-${day} ${hour}:${minutes}:${seconds}`;
			case "delivery":
				return `${hour}:${minutes}`;
			default:
				return `${year}-${month}-${day}`;
		}
	},
	 /**
	  * @author 曹连存 2024年3月8日15:26:08
	  * updateFile 
	  * @description 小程序移动端文件上传方法 
	  * @param {String} serverData.key -文件存储路径 - 非必填
	  * @param {String} serverData.filePath 文件路径 - 必填！
	  * @param {String} serverData.AccessKeyID obs服务器id - 非必填
	  * @param {String} serverData.SecretKey obs服务器秘钥 - 非必填
	  * @param {String} serverData.bucket obs桶名 - 非必填
	  * @param {String} serverData.server obs服务器地址 - 非必填 
	  * @param {String} model 模式 默认auto 自动上传到华为obs 可选 handMovement - 非必填 
	  * @return {Promise|Object} 根据模式不同返回不同的数据 自动模式返回 Promise<上传完成的数据> 手动模式返回处理好的数据
	  * @example updateFile(serverData).then(res=>{
	 	 console.log("上传成功")
	  })
	  */
	 updateFile({ 
	 	key = "images",
	 	filePath,
	 	AccessKeyID = "M4ZOVKHYAA6O1FM2S9EL",
	 	SecretKey = "3QFqnrvzmUelRSbsVDG5APtlnPseyrtYkApMpV4e",
	 	bucket = "ysmarket",
	 	server = "obs.cn-east-3.myhuaweicloud.com"
	 }, model = "auto") {
	 	// 文件上传地址 https://桶名.服务器地址
	 	const url = `https://${bucket}.${server}`;
	 	// 没有文件地址直接返回
	 	if (!filePath) return;
	 	// 文件名写死
	 	const name = "file";
	 	//解析文件地址，配置obj 需要的key
	 	const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
	 	// 通过文件名字生成obs文件地址 格式 文件夹/当前日期文件夹/UUID-文件名.类型
	 	const outKey = `${key}/${this.getNowDate()}/${this.getUUID()}-${fileName}`;
	 	// 接口失效时间 秒
	 	const expires = 120;
	 	// 生成签名需要的参数
	 	const OBSPolicy = {
	 		// 设定policy内容，policy规则定义可参考步骤3中的超链接签名计算规则文档
	 		"expiration": this.getNowDate(new Date(new Date().setSeconds(expires)), "huawei"), //时间接口有效时间
	 		"conditions": [{
	 				"bucket": bucket // 桶名
	 			},
	 			{
	 				'key': outKey //文件上传地址
	 			},
	 			{
	 				"x-obs-acl": "public-read" //设置公共读
	 			},
	 		]
	 	}
	 	const policy = this.getPolicyEncode(OBSPolicy); // 计算base64编码后的policy
	 	// 根据返回的数据生成计算机签名
	 	const signature = this.getSignature(policy, SecretKey);
	 	//上传需要的参数
	 	const formData = {
	 		'x-obs-acl': 'public-read', //公共读
	 		AccessKeyID, //服务器id
	 		policy, // policy
	 		signature, //计算机签名
	 		'key': outKey // 文件地址
	 	}
	 	// 开始上传
	 	switch (model) {
	 		case "auto":
	 			return new Promise((re, rj) => {
	 				uni.uploadFile({
	 					url,
	 					filePath,
	 					name,
	 					formData,
	 					success(res) {
	 						re({
	 							...res,
	 							url: `https://${bucket}.${server}/${outKey}`,
	 							outKey //用于删除文件
	 						})
	 					},
	 					fail(err) {
	 						rj(err)
	 					}
	 				})
	 			});
	 		case "handMovement":
	 			return {
	 				url,
	 				filePath,
	 				name,
	 				formData,
	 			}
	 	}
	 
	 },
};